package com.hnu.store.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.hnu.store.dto.NftDTO;
import com.hnu.store.entity.User;
import com.hnu.store.entity.Work;
import com.hnu.store.mapper.UserMapper;
import com.hnu.store.mapper.WorkMapper;
import com.hnu.store.service.IWorkService;
import com.hnu.store.service.ex.DeleteNftException;
import com.hnu.store.service.ex.EditNftException;
import com.hnu.store.service.ex.FileNotFoundException;
import com.hnu.store.service.ex.FileReceiveException;
import com.hnu.store.service.ex.FileTypeException;
import com.hnu.store.service.ex.NftListException;
import com.hnu.store.service.ex.ServiceException;
import com.hnu.store.service.ex.UploadException;
import com.hnu.store.service.ex.WorkNotExistException;
import com.hnu.store.utils.CutAudio;
import com.hnu.store.utils.CutImage;
import com.hnu.store.utils.CutText;
import com.hnu.store.utils.FileHashUtils;
import com.hnu.store.utils.GenerateWorkUri;
import com.hnu.store.utils.IpfsUtil;
import com.hnu.store.utils.PdfUtils;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


@Service
public class WorkServiceImpl implements IWorkService {

  @Autowired
  private WorkMapper workMapper;
  @Autowired
  private UserMapper userMapper;

  @Override
  public List<NftDTO> getNftList(Integer userId, String stringPara, String status,
      String classification) {
    List<Work> workList = workMapper.getListByUserId(userId);
    if (workList.isEmpty()) {
      throw new NftListException("用户无作品");
    }
    //  创建dtoList
    ArrayList<NftDTO> nftList = new ArrayList<>();
    for (Work it : workList) {

      NftDTO item = new NftDTO();
      if (!it.getWorkName().contains(stringPara)) {
        continue;
      }
      item.setName(it.getWorkName());
      item.setId(it.getId());
      switch (it.getStatus()) {
        case 0:
          item.setStatus("未存证");
          break;
        case 1:
          item.setStatus("已存证");
          break;
        case 2:
          item.setStatus("已转让");
          break;
        default:
          item.setStatus("错误");
          break;
      }
      if (!item.getStatus().equals(status) && !status.isEmpty()) {
        continue;
      }
      switch (it.getType()) {
        case 1:
          item.setType("摄影作品");
          break;
        case 2:
          item.setType("文字作品");
          break;
        case 3:
          item.setType("影视作品");
          break;
        case 4:
          item.setType("音乐作品");
          break;
        case 5:
          item.setType("美术作品");
          break;
        default:
          item.setType("未设定");
          break;
      }
      if (!item.getType().equals(classification) && !classification.isEmpty()) {
        continue;
      }
      item.setCreatedTime(it.getCreatedTime());
      item.setTag1(it.getWorkTag1());
      item.setTag2(it.getWorkTag2());
      item.setTag3(it.getWorkTag3());
      item.setFileName(it.getFileName());
      item.setFileDownloadUrl(it.getFileDownloadUrl());
      item.setFileHash(it.getFileHash());
      nftList.add(item);
    }
    return nftList;
  }

  @Override
  public List<NftDTO> getAllNft() {
    List<Work> workList = workMapper.getAllWork();
    if (workList.isEmpty()) {
      throw new NftListException("系统中无作品");
    }
    //  创建dtoList
    ArrayList<NftDTO> nftList = new ArrayList<>();
    for (Work it : workList) {
      NftDTO item = new NftDTO();
      item.setName(it.getWorkName());
      item.setId(it.getId());
      switch (it.getType()) {
        case 1:
          item.setType("摄影作品");
          break;
        case 2:
          item.setType("文字作品");
          break;
        case 3:
          item.setType("影视作品");
          break;
        case 4:
          item.setType("音乐作品");
          break;
        case 5:
          item.setType("美术作品");
          break;
        default:
          item.setType("未设定");
          break;
      }
      item.setCreatedTime(it.getCreatedTime());
      item.setTag1(it.getWorkTag1());
      item.setTag2(it.getWorkTag2());
      item.setTag3(it.getWorkTag3());
      item.setFileName(it.getFileName());
      item.setFileDownloadUrl(it.getFileDownloadUrl());
      item.setFileHash(it.getFileHash());
      nftList.add(item);
    }
    return nftList;
  }

  @Override
  public void downloadNft(String filePath, String fileName, HttpServletResponse response) {
    //  根据文件路径获取文件
    try {
      filePath = URLDecoder.decode(filePath,"UTF-8");
      fileName = URLDecoder.decode(fileName,"UTF-8");
    } catch (UnsupportedEncodingException e) {
      System.out.println("下载nft时解码错误");
      e.printStackTrace();
    }

    File file = new File(filePath+File.separator+fileName);
    if (!file.exists()) {
      throw new FileNotFoundException("http请求的文件不存在");
    }
    //  配置文件下载
    response.setHeader("content-type", "application/octet-stream");
    response.setContentType("application/octet-stream");
    // 下载文件能正常显示中文
    try {
      response.setHeader("Content-Disposition",
          "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
    } catch (UnsupportedEncodingException e) {
      System.out.println("downloadNft获得文件过程中encode失败");
      e.printStackTrace();
    }
    // 实现文件下载
    byte[] buffer = new byte[1024];
    try {
      FileInputStream fis = new FileInputStream(file);
      OutputStream os = response.getOutputStream();
      while ((fis.read(buffer)) != -1) {
        os.write(buffer);
        os.flush();
      }
      os.close();
    } catch (Exception e) {
      System.out.println("写入HttpServletResponse错误" + e);
      e.printStackTrace();
    }
  }

  @Override
  public void uploadChain(String id, String chainHash, Integer status, String blockHeight,
      String chainTime) {
    //  上链信息更新
    Work work = workMapper.getWorkById(id);
    work.setChainHash(chainHash);
    work.setStatus(status);
    workMapper.update(work);
  }

  @Override
  public void viewDetails(String workId,String chainTime,String blockHeight) {
    Work work = workMapper.getWorkById(workId);
    //  如果是第一次查看已上链作品的信息
    if(work.getStatus()==1&&work.getCertificateFileLocation()==null) {
      User user = userMapper.findById(work.getUserId());
      work.setChainTime(chainTime);
      work.setBlockHeight(blockHeight);
      //  生成存证文件
      PdfUtils pdfUtils = new PdfUtils();
      String certificateFileLocation = pdfUtils.depositCertificatePdfOut(work,user,chainTime,blockHeight);
      work.setCertificateFileLocation("http://124.222.70.223:8081/work/downloadNft?filePath="
          + certificateFileLocation + "&fileName=NFTCertificate.pdf");
      //  更新work信息
      workMapper.update(work);
    }
  }

  @Override
  public Work addNft(MultipartFile multipartFile, Work work) {
    String fileName = multipartFile.getOriginalFilename();
    String fileType = fileName.substring(fileName.indexOf('.')+1);
    int workType = work.getType();
    if(workType==1||workType==5) {
      if(!fileType.equals("jpg") && !fileType.equals("png")) {
        throw new FileTypeException("文件类型错误");
      }
    } else if (workType==2) {
      if(!fileType.equals("txt") && !fileType.equals("doc") && !fileType.equals("docx")) {
        throw new FileTypeException("文件类型错误");
      }
    } else if (workType==3) {
      if(!fileType.equals("mp4")) {
        throw new FileTypeException("文件类型错误");
      }
    } else if (workType==4) {
      if(!fileType.equals("mp3") && !fileType.equals("wav")) {
        throw new FileTypeException("文件类型错误");
      }
    }
    String dirName = "nft";
    String id = IdWorker.getIdStr(work);
    String path = System.getProperty("user.dir") + File.separator + dirName + File.separator + id;
    Date date = new Date();
    work.setCreatedTime(date);
    work.setModifiedTime(date);
    String username = userMapper.findById(work.getUserId()).getUsername();
    work.setCreatedUser(username);
    work.setModifiedUser(username);

    if (multipartFile != null) {
      work.setFileName(fileName);
      try {
        String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
        work.setFileLocation(URLEncoder.encode(path, "UTF-8"));
        work.setFileDownloadUrl(
            "http://124.222.70.223:8081/work/downloadNft?filePath="
                + work.getFileLocation() + "&fileName=" + encodeFileName);
      } catch (UnsupportedEncodingException e) {
        throw new UploadException("转码异常");
      }
      work.setStatus(0);
      File fileDir = new File(path);
      if (!fileDir.exists() && !fileDir.isDirectory()) {
        fileDir.mkdirs();
      }
      File file = new File(fileDir, Objects.requireNonNull(multipartFile.getOriginalFilename()));
      try {
        multipartFile.transferTo(file);
      } catch (IOException e) {
        throw new UploadException("nft文件上传异常");
      }

      String fileHashMD5 = FileHashUtils.MD5.checksum(file);
      work.setFileHash(fileHashMD5);
      work.setId(id);

      String workUriLocation = GenerateWorkUri.generateWorkUri(work, path);
      if (workUriLocation == null) {
        throw new UploadException("生成uri失败");
      }
      String workUri;
      try {
        //  ipfs上传作品相关描述的json，生成链接
        workUri = IpfsUtil.upload(workUriLocation);
      } catch (IOException e) {
        e.printStackTrace();
        throw new UploadException("ipfs上传失败");
      }
      work.setWorkUri(workUri);

      int rows = workMapper.insert(work);
      if (rows != 1) {
        throw new UploadException("数据库插入异常");
      }
      //  无异常情况，把work的信息返回给前端
      return work;
    } else {
      throw new FileReceiveException("前端没有上传文件或上传失败");
    }
  }

  @Override
  public void addPicturePieces(MultipartFile multipartFile, Work work , int rows , int cols)
      throws IOException {
    String dirName = "nft";
    String originalFilename = multipartFile.getOriginalFilename();
    //  获取文件类型jpg png等
    String fileType = originalFilename.substring(originalFilename.indexOf('.')+1);
    //  上传文件类型错误
    if(!fileType.equals("jpg")&&!fileType.equals("png")) {
      throw new FileTypeException("上传文件类型错误");
    }
    String name = originalFilename.substring(0,originalFilename.indexOf('.'));
    String tempPath = System.getProperty("user.dir") + File.separator + dirName;
    //  创建临时文件，用于拆分
    File tempFile = new File(tempPath, Objects.requireNonNull(originalFilename));

    if(multipartFile!=null) {
      try {
        multipartFile.transferTo(tempFile);
      } catch (IOException e) {
        throw new UploadException("nft文件上传异常");
      }
    } else {
      throw new FileReceiveException("前端没有上传文件或上传失败");
    }
    //  拆分图片工具类获取拆分好的图片数组
    BufferedImage imgs[] = CutImage.splitImage(tempPath + File.separator + originalFilename,rows,cols);
    //  文件数量
    int count = rows * cols;
    Work[] works = new Work[count];
    String workName = work.getWorkName();
    int userId = work.getUserId();
    int type = work.getType();
    String introduction = work.getIntroductionUrl();
    String copyrightOwnerId = work.getCopyrightOwnerId();
    String copyrightOwnerName = work.getCopyrightOwnerName();
    int copyrightOwnerType  = work.getCopyrightOwnerType();
    String workTag1 = work.getWorkTag1();
    String workTag2 = work.getWorkTag2();
    String workTag3 = work.getWorkTag3();
    String username = userMapper.findById(userId).getUsername();
    Date date = new Date();

    for (int i=0;i<count;i++) {
      works[i] = new Work();
      works[i].setWorkName(workName+"-"+(i+1));
      works[i].setUserId(userId);
      works[i].setType(type);
      works[i].setIntroductionUrl(introduction);
      works[i].setStatus(0);
      works[i].setCopyrightOwnerId(copyrightOwnerId);
      works[i].setCopyrightOwnerName(copyrightOwnerName);
      works[i].setCopyrightOwnerType(copyrightOwnerType);
      works[i].setWorkTag1(workTag1);
      works[i].setWorkTag2(workTag2);
      works[i].setWorkTag3(workTag3);
      works[i].setCreatedUser(username);
      works[i].setModifiedUser(username);
      works[i].setCreatedTime(date);
      works[i].setModifiedTime(date);

      //  每个小部分生成id
      String id = IdWorker.getIdStr(works[i]);
      String path = System.getProperty("user.dir") + File.separator + dirName + File.separator + id;
      //  设置文件名，如test-1.jpg
      String fileName = name+"-"+(i+1)+'.'+fileType;
      works[i].setFileName(fileName);

      try {
        String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
        works[i].setFileLocation(URLEncoder.encode(path, "UTF-8"));
        works[i].setFileDownloadUrl(
            "http://124.222.70.223:8081/work/downloadNft?filePath="
                + works[i].getFileLocation() + "&fileName=" + encodeFileName);
      } catch (UnsupportedEncodingException e) {
        throw new UploadException("转码异常");
      }
      //  创建目录
      File fileDir = new File(path);
      if (!fileDir.exists() && !fileDir.isDirectory()) {
        fileDir.mkdirs();
      }
      //  写入拆分后的文件
      File file = new File( path + File.separator +fileName);
      ImageIO.write(imgs[i], fileType, file);
      //  生成文件哈希
      String fileHashMD5 = FileHashUtils.MD5.checksum(file);
      works[i].setFileHash(fileHashMD5);
      works[i].setId(id);

      String workUriLocation = GenerateWorkUri.generateWorkUri(works[i], path);
      if (workUriLocation == null) {
        throw new UploadException("生成uri失败");
      }
      String workUri;
      try {
        //  ipfs上传作品相关描述的json，生成链接
        workUri = IpfsUtil.upload(workUriLocation);
      } catch (IOException e) {
        e.printStackTrace();
        throw new UploadException("ipfs上传失败");
      }
      works[i].setWorkUri(workUri);
      if (workMapper.insert(works[i]) != 1) {
        throw new UploadException("数据库插入异常");
      }
    }
    //  循环完成，拆分结束，删除临时文件
    if(!tempFile.delete()) {
      System.out.println("删除文件失败");
    }
  }

  @Override
  public void addAudioPieces(MultipartFile multipartFile, Work work, int count) {
    String dirName = "nft";
    String originalFilename = multipartFile.getOriginalFilename();
    //  获取文件类型wav mp3等
    String fileType = originalFilename.substring(originalFilename.indexOf('.')+1);
    //  上传文件类型错误
    if(!fileType.equals("wav")&&!fileType.equals("mp3")) {
      throw new FileTypeException("上传文件类型错误");
    }
    String name = originalFilename.substring(0,originalFilename.indexOf('.'));
    String tempPath = System.getProperty("user.dir") + File.separator + dirName;
    //  创建临时文件，用于拆分
    File tempFile = new File(tempPath, Objects.requireNonNull(originalFilename));

    if(multipartFile!=null) {
      try {
        multipartFile.transferTo(tempFile);
      } catch (IOException e) {
        throw new UploadException("nft文件上传异常");
      }
    } else {
      throw new FileReceiveException("前端没有上传文件或上传失败");
    }

    Work[] works = new Work[count];
    String workName = work.getWorkName();
    int userId = work.getUserId();
    int type = work.getType();
    String introduction = work.getIntroductionUrl();
    String copyrightOwnerId = work.getCopyrightOwnerId();
    String copyrightOwnerName = work.getCopyrightOwnerName();
    int copyrightOwnerType  = work.getCopyrightOwnerType();
    String workTag1 = work.getWorkTag1();
    String workTag2 = work.getWorkTag2();
    String workTag3 = work.getWorkTag3();
    String username = userMapper.findById(userId).getUsername();
    Date date = new Date();

    for (int i=0;i<count;i++) {
      works[i] = new Work();
      works[i].setWorkName(workName+"-"+(i+1));
      works[i].setUserId(userId);
      works[i].setType(type);
      works[i].setIntroductionUrl(introduction);
      works[i].setStatus(0);
      works[i].setCopyrightOwnerId(copyrightOwnerId);
      works[i].setCopyrightOwnerName(copyrightOwnerName);
      works[i].setCopyrightOwnerType(copyrightOwnerType);
      works[i].setWorkTag1(workTag1);
      works[i].setWorkTag2(workTag2);
      works[i].setWorkTag3(workTag3);
      works[i].setCreatedUser(username);
      works[i].setModifiedUser(username);
      works[i].setCreatedTime(date);
      works[i].setModifiedTime(date);

      //  每个小部分生成id
      String id = IdWorker.getIdStr(works[i]);
      String path = System.getProperty("user.dir") + File.separator + dirName + File.separator + id;
      //  设置文件名，如test-1.mp3
      String fileName = name+"-"+(i+1)+".wav";
      works[i].setFileName(fileName);

      try {
        String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
        works[i].setFileLocation(URLEncoder.encode(path, "UTF-8"));
        works[i].setFileDownloadUrl(
            "http://124.222.70.223:8081/work/downloadNft?filePath="
                + works[i].getFileLocation() + "&fileName=" + encodeFileName);
      } catch (UnsupportedEncodingException e) {
        throw new UploadException("转码异常");
      }
      //  创建目录
      File fileDir = new File(path);
      if (!fileDir.exists() && !fileDir.isDirectory()) {
        fileDir.mkdirs();
      }
      //  写入拆分后的文件
      if(fileType.equals("mp3")) {
        //  字符数组
        byte[] music = CutAudio.getBytes(tempPath+File.separator+originalFilename);
        //  转换为wav临时文件
        if(CutAudio.byteToWav(music,tempPath+File.separator+name+".wav")) {
          System.out.println("转换成功");
        } else {
          System.out.println("转换失败");
        }
        File file = new File( tempPath+File.separator+name+".wav");
        int length = ((int) CutAudio.getTimeLen(file))/count;
        //  拆分
        CutAudio.cut(tempPath+File.separator+name+".wav",path+File.separator+fileName,i*length,(i+1)*length);
        if(!file.delete()) {
          System.out.println("删除wav临时文件失败");
        }
      } else {
        //  直接拆分，无需转换为wav
        int length = ((int) CutAudio.getTimeLen(tempFile))/count;
        CutAudio.cut(tempPath+File.separator+originalFilename,path+File.separator+fileName,i*length,(i+1)*length);
      }
      //  生成文件哈希
      File file = new File(path+File.separator+fileName);
      String fileHashMD5 = FileHashUtils.MD5.checksum(file);
      works[i].setFileHash(fileHashMD5);
      works[i].setId(id);

      String workUriLocation = GenerateWorkUri.generateWorkUri(works[i], path);
      if (workUriLocation == null) {
        throw new UploadException("生成uri失败");
      }
      String workUri;
      try {
        //  ipfs上传作品相关描述的json，生成链接
        workUri = IpfsUtil.upload(workUriLocation);
      } catch (IOException e) {
        e.printStackTrace();
        throw new UploadException("ipfs上传失败");
      }
      works[i].setWorkUri(workUri);
      if (workMapper.insert(works[i]) != 1) {
        throw new UploadException("数据库插入异常");
      }
    }
    //  循环完成，拆分结束，删除临时文件
    if(!tempFile.delete()) {
      System.out.println("删除文件失败");
    }

  }

  /**
   * 文本作品拆分
   * @param multipartFile 文件
   * @param work 作品信息
   * @param count 拆分数目
   * 目前只能拆分txt文件
   */
  @Override
  public void addTextPieces(MultipartFile multipartFile, Work work, int count) {
    String dirName = "nft";
    String originalFilename = multipartFile.getOriginalFilename();
    //  获取文件名（不含文件后缀），以及临时文件的路径
    String name = originalFilename.substring(0,originalFilename.indexOf('.'));
    //  获取文件类型
    String fileType = originalFilename.substring(originalFilename.indexOf('.')+1);
    //  上传文件类型错误
    if(!fileType.equals("txt")) {
      throw new FileTypeException("上传文件类型错误");
    }
    String tempPath = System.getProperty("user.dir") + File.separator + dirName;
    //  创建临时文件，用于拆分
    File tempFile = new File(tempPath, Objects.requireNonNull(originalFilename));

    if(multipartFile!=null) {
      try {
        multipartFile.transferTo(tempFile);
      } catch (IOException e) {
        throw new UploadException("nft文件上传异常");
      }
    } else {
      throw new FileReceiveException("前端没有上传文件或上传失败");
    }

    Work[] works = new Work[count];
    String workName = work.getWorkName();
    int userId = work.getUserId();
    int type = work.getType();
    String introduction = work.getIntroductionUrl();
    String copyrightOwnerId = work.getCopyrightOwnerId();
    String copyrightOwnerName = work.getCopyrightOwnerName();
    int copyrightOwnerType  = work.getCopyrightOwnerType();
    String workTag1 = work.getWorkTag1();
    String workTag2 = work.getWorkTag2();
    String workTag3 = work.getWorkTag3();
    String username = userMapper.findById(userId).getUsername();
    Date date = new Date();
    int rows;
    //  临时文件的总行数
    try {
      rows = CutText.readFile(tempPath+File.separator+originalFilename);
    } catch (java.io.FileNotFoundException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
    int piece = rows/count;

    for (int i=0;i<count;i++) {
      works[i] = new Work();
      works[i].setWorkName(workName+"-"+(i+1));
      works[i].setUserId(userId);
      works[i].setType(type);
      works[i].setIntroductionUrl(introduction);
      works[i].setStatus(0);
      works[i].setCopyrightOwnerId(copyrightOwnerId);
      works[i].setCopyrightOwnerName(copyrightOwnerName);
      works[i].setCopyrightOwnerType(copyrightOwnerType);
      works[i].setWorkTag1(workTag1);
      works[i].setWorkTag2(workTag2);
      works[i].setWorkTag3(workTag3);
      works[i].setCreatedUser(username);
      works[i].setModifiedUser(username);
      works[i].setCreatedTime(date);
      works[i].setModifiedTime(date);

      //  每个小部分生成id
      String id = IdWorker.getIdStr(works[i]);
      String path = System.getProperty("user.dir") + File.separator + dirName + File.separator + id;
      //  设置文件名，如test-1.txt
      String fileName = name+"-"+(i+1)+".txt";
      works[i].setFileName(fileName);

      try {
        String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
        works[i].setFileLocation(URLEncoder.encode(path, "UTF-8"));
        works[i].setFileDownloadUrl(
            "http://124.222.70.223:8081/work/downloadNft?filePath="
                + works[i].getFileLocation() + "&fileName=" + encodeFileName);
      } catch (UnsupportedEncodingException e) {
        throw new UploadException("转码异常");
      }
      //  创建目录
      File fileDir = new File(path);
      if (!fileDir.exists() && !fileDir.isDirectory()) {
        fileDir.mkdirs();
      }

      //  拆分文件
      if(i!=count-1) {
        CutText.cut(tempPath+File.separator+originalFilename,path+File.separator+fileName,1+piece*i,piece*(i+1));
      } else {
        CutText.cut(tempPath+File.separator+originalFilename,path+File.separator+fileName,1+piece*i,rows);
      }

      //  生成文件哈希
      File file = new File(path+File.separator+fileName);
      String fileHashMD5 = FileHashUtils.MD5.checksum(file);
      works[i].setFileHash(fileHashMD5);
      works[i].setId(id);

      String workUriLocation = GenerateWorkUri.generateWorkUri(works[i], path);
      if (workUriLocation == null) {
        throw new UploadException("生成uri失败");
      }
      String workUri;
      try {
        //  ipfs上传作品相关描述的json，生成链接
        workUri = IpfsUtil.upload(workUriLocation);
      } catch (IOException e) {
        e.printStackTrace();
        throw new UploadException("ipfs上传失败");
      }
      works[i].setWorkUri(workUri);
      if (workMapper.insert(works[i]) != 1) {
        throw new UploadException("数据库插入异常");
      }
    }
    //  循环完成，拆分结束，删除临时文件
    if(!tempFile.delete()) {
      System.out.println("删除文件失败");
    }

  }

  /**
   * 预览图片
   * @param multipartFile 文件
   * @return 图片url
   */
  @Override
  public String preview(MultipartFile multipartFile) {
    String path = System.getProperty("user.dir") + File.separator + "nft";
    String fileName = multipartFile.getOriginalFilename();
    File tempFile = new File(path, Objects.requireNonNull(fileName));
    //  上传文件
    if(multipartFile!=null) {
      try {
        multipartFile.transferTo(tempFile);
      } catch (IOException e) {
        throw new UploadException("nft文件上传异常");
      }
    } else {
      throw new FileReceiveException("前端没有上传文件或上传失败");
    }
    //  上传成功，返回文件url即可
    try {
      return "http://124.222.70.223:8081/work/downloadNft?filePath="+URLEncoder.encode(path, "UTF-8")+"&fileName="+URLEncoder.encode(fileName, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      System.out.println("编码错误");
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }

  @Override
  public void cancelPreview(MultipartFile multipartFile) {
    //  获取文件
    String path = System.getProperty("user.dir") + File.separator + "nft";
    String fileName = multipartFile.getOriginalFilename();
    File tempFile = new File(path, Objects.requireNonNull(fileName));
    if(!tempFile.delete()) {
      throw new ServiceException("删除预览图片失败");
    }
  }

  @Override
  public Work getWorkById(String workId) {
    Work work = workMapper.getWorkById(workId);
    if (work == null) {
      throw new WorkNotExistException("该Id没有找到NFT");
    }
    return work;
  }

  @Override
  public void deleteNft(String id) {
    Work work = workMapper.getWorkById(id);
    File dir;
    try {
      dir = new File(URLDecoder.decode(work.getFileLocation(), "UTF-8"));
    } catch (UnsupportedEncodingException e) {
      throw new DeleteNftException("编码错误");
    }
    File file = new File(dir + File.separator + work.getFileName());
    if (!file.delete()) {
      throw new DeleteNftException("删除作品文件出现异常");
    }
    File json = new File(dir + File.separator + id + ".json");
    if (!json.delete()) {
      throw new DeleteNftException("删除json文件出现异常");
    }
    if (!dir.delete()) {
      throw new DeleteNftException("删除文件夹出现异常");
    }

    Integer rows = workMapper.delete(id);

    if (rows != 1) {
      throw new DeleteNftException("t_work删除出现异常");
    }
  }

  @Override
  public Work editNft(MultipartFile multipartFile, Work work) {
    /*
      有文件，上链前的调用，可以对nft进行编辑
     */
    if (multipartFile != null) {
      String dirName = "nft";
      String path =
          System.getProperty("user.dir") + File.separator + dirName + File.separator + work.getId();
      File oldFile = new File(
          path + File.separator + workMapper.getWorkById(work.getId()).getFileName());

      String fileName = multipartFile.getOriginalFilename();
      work.setFileName(fileName);
      try {
        assert fileName != null;
        String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
        work.setFileDownloadUrl(
            "http://124.222.70.223:8081/work/downloadNft?filePath="
                + work.getFileLocation() + "&fileName=" + encodeFileName);
      } catch (UnsupportedEncodingException e) {
        throw new UploadException("转码异常");
      }

      File file = new File(path, Objects.requireNonNull(multipartFile.getOriginalFilename()));

      if (!oldFile.delete()) {
        System.out.println(oldFile.getPath());
        throw new EditNftException("删除旧文件失败");
      }
      //  删除文件成功
      try {
        multipartFile.transferTo(file);
      } catch (IOException e) {
        throw new UploadException("nft文件更新异常");
      }

      String fileHashMD5 = FileHashUtils.MD5.checksum(file);
      work.setFileHash(fileHashMD5);

      String workUriLocation = GenerateWorkUri.generateWorkUri(work, path);
      if (workUriLocation == null) {
        throw new UploadException("生成uri失败");
      }
      String workUri;
      try {
        //  ipfs上传作品相关描述的json，生成链接
        workUri = IpfsUtil.upload(workUriLocation);
      } catch (IOException e) {
        e.printStackTrace();
        throw new UploadException("ipfs上传失败");
      }
      work.setWorkUri(workUri);

      int rows = workMapper.update(work);
      if (rows != 1) {
        throw new EditNftException("修改work表发生异常");
      }
      //  无异常情况，把work的信息返回给前端
      return workMapper.getWorkById(work.getId());
    } else {
      /*
        没有文件的情况，直接修改数据库即可
        上链前不传文件的话只改基本信息
       */
      int rows = workMapper.update(work);
      if (rows != 1) {
        throw new EditNftException("修改work表发生异常");
      }
      //  返回更新后的work数据给前端
      return workMapper.getWorkById(work.getId());
    }
  }

}
